var _ = require('lodash'),
    Q = require('q'),
    mongoose = require('mongoose'),
    PublicEnum = require('../../../Base/server/controllers/Enum'),
    Transaction = require('../../../Base/server/controllers/Transaction'),
    entityCollection = require('../../../Base/server/controllers/EntityCollection'),
    barcodeMasterController = require('../../../Barcode/server/controllers/BarcodeMaster.server.controller'),
    kanbanDemandController = require('../../../ProduceWork/server/controllers/KanbanDemand.server.controller'),
    connectAreaController = require('../../../CBO/server/controllers/ConnectArea.server.controller');

exports.createKanban = function (req, res) {
    var parameter = req.body.Parameter,
        barcode = parameter.Barcode,
        userId = req.user._id;

    checkKanbanExist(barcode).then(function (result) {
        return Q.when(result.exist ? result.MO : createKanbanRecords(result.MO, userId));
    }).then(function (results) {
        res.json({
            Data: true,
            Error: null
        });
    }).catch(function (err) {
            res.json({
                Data: null,
                Error: err
            });
        })
        .done();
};

function checkKanbanExist(barcode) {
    var deferred = Q.defer();

    barcodeMasterController.findBarcodeMaster(barcode, function (err, barcodeMaster) {
        if (err) {
            deferred.reject(err);
            return;
        }
        if (!barcodeMaster || barcodeMaster.BarcodeType != 0) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询物料错误';
            newErr.message = '无法识别的芯片，请重新扫描！';
            deferred.reject(newErr);
            return;
        }
        kanbanDemandController.findOneByMoId(barcodeMaster.MO, function (err, demands) {
            if (err) {
                deferred.reject(err);
                return;
            }
            deferred.resolve({
                exist: demands ? true : false,
                MO: barcodeMaster.MO
            });
        });
    });

    return deferred.promise;
}

function createKanbanRecords(Mo, userId) {
    var deferred = Q.defer();

    connectAreaController.distinctId(function (err, areaIds) {
        if (err) {
            deferred.reject(err);
            return;
        }
        var kanbanDemandRecords = [];
        _.forEach(areaIds, function (areaId) {
            kanbanDemandRecords.push({
                RowStatus: PublicEnum.RowStatus.Insert,
                CreatedBy: userId,
                MO: Mo,
                ConnectArea: areaId
            });
        });
        Transaction.BatchSaveByTran([
                {EntityName: 'KanbanDemand', Records: kanbanDemandRecords}
            ],
            function (err, result) {
                if (err) {
                    deferred.reject(err);
                    return;
                }
                deferred.resolve(result);
            }
        );
    });

    return deferred.promise;
}

//获取上游看板需求
exports.GetUpStreamKanban = function (req, res) {
    var parameter = req.body.Parameter,
        userId = parameter.userId;
    getConnectArea(userId, true).then(function (connectArea) {
        Q.all([
            getRvRecordsByConnectArea(connectArea._id),
            getKanbanDemand({
                ConnectArea: connectArea._id,
                $where: "this.TotalDemandQty - this.TotalStockQty > 0"
            })
        ]).spread(function () {
            var rvRecords = arguments[0],
                demands = arguments[1],
                kanban = [];
            _.forEach(rvRecords, function (rvRecord) {
                _.forEach(demands, function (demand) {
                    if (rvRecord._id.toString() == demand.MO.toString()) {
                        kanban.push({
                            Priority: demand.Priority == undefined ? 0 : demand.Priority,
                            NOLotNumber: rvRecord.value.barcode.MOLotNumber == undefined ? '' : rvRecord.value.barcode.MOLotNumber,
                            ItemMasterCode: rvRecord.value.barcode.ItemMasterCode == undefined ? '' : rvRecord.value.barcode.ItemMasterCode,
                            ItemMasterName: rvRecord.value.barcode.ItemMasterName == undefined ? '' : rvRecord.value.barcode.ItemMasterName,
                            TotalDemandQty: demand.TotalDemandQty == undefined ? 0 : demand.TotalDemandQty,
                            TotalNeedQty: (demand.TotalDemandQty - demand.TotalStockQty) == undefined ? 0 : (demand.TotalDemandQty - demand.TotalStockQty),
                            RcvQty: rvRecord.value.RcvQty == undefined ? 0 : demand.RcvQty,
                            TotalStockQty: demand.TotalStockQty == undefined ? 0 : demand.TotalStockQty,
                            TotalReceiveQty: demand.TotalReceiveQty == undefined ? 0 : demand.TotalReceiveQty
                        });
                    }
                });
            });
            res.json({
                Data: kanban,
                Error: null
            });
        });
    });

};

//获取下游看板需求
exports.GetDownStreamKanban = function (req, res) {
    var parameter = req.body.Parameter,
        userId = parameter.userId;
    //入库记录(批次(工单)-库存)
    getConnectArea(userId, false).then(function (connectArea) {
        Q.all([
            getRvRecordsByConnectArea(connectArea._id),
            getKanbanDemand({
                ConnectArea: connectArea._id,
                $where: "this.TotalDemandQty - this.TotalReceiveQty > 0"
            })
        ]).spread(function () {
            var rvRecords = arguments[0],
                demands = arguments[1],
                kanban = [];
            _.forEach(rvRecords, function (rvRecord) {
                _.forEach(demands, function (demand) {
                    if (rvRecord._id.toString() == demand.MO.toString()) {
                        kanban.push({
                            Priority: demand.Priority == undefined ? 0 : demand.Priority,
                            NOLotNumber: rvRecord.value.barcode.MOLotNumber == undefined ? '' : rvRecord.value.barcode.MOLotNumber,
                            ItemMasterCode: rvRecord.value.barcode.ItemMasterCode == undefined ? '' : rvRecord.value.barcode.ItemMasterCode,
                            ItemMasterName: rvRecord.value.barcode.ItemMasterName == undefined ? '' : rvRecord.value.barcode.ItemMasterName,
                            RcvQty: rvRecord.value.RcvQty == undefined ? 0 : demand.RcvQty,
                            TotalReceiveQty: demand.TotalReceiveQty == undefined ? 0 : demand.TotalReceiveQty,
                            NeedDeliveryQty: (demand.TotalDemandQty - demand.TotalReceiveQty) == undefined ? 0 : (demand.TotalDemandQty - demand.TotalReceiveQty)
                        });
                    }
                });
            });
            res.json({
                Data: kanban,
                Error: null
            });
        });
    });
};

//交接区检货UdpatePIckUpQty
exports.UdpatePIckUpQty = function (req, res) {
    var parameter = req.body.Parameter,
        userId = parameter.userId,
        validBarcodeList = parameter.validBarcodeList,
        invalidBarcodeList = parameter.invalidBarcodeList;
    Q.all([
        getConnectArea(userId, true),
        queryByBarcodeAndGroupByMo('MO', validBarcodeList),
        getRcvRecordsByBarcode(validBarcodeList),
        getRcvRecordsByBarcode(invalidBarcodeList)
    ]).spread(function () {
        var connectAreaInfo = arguments[0],
            barcodeInfoArray = arguments[1],
            rcvRecords = arguments[2],
            inRcvRecords = arguments[3],
            MoArr = [],
            kanbanArr = [];

        if (connectAreaInfo && barcodeInfoArray.length > 0) {
            _.forEach(barcodeInfoArray, function (r) {
                MoArr.push(r._id);
            });
            getKanbanDemand({
                MO: {$in: MoArr},
                ConnectArea: connectAreaInfo._id
            }).then(function (data) {
                for (var i = 0; i < barcodeInfoArray.length; i++) {
                    _.forEach(data, function (r) {
                        if (barcodeInfoArray[i]._id.toString() == r.MO.toString() &&
                            connectAreaInfo._id.toString() == r.ConnectArea.toString()) {
                            r.TotalStockQty += barcodeInfoArray[i].value;
                            r.RowStatus = PublicEnum.RowStatus.Modify;
                        }
                    });
                }
                kanbanArr = data;
                //0:推式，1: 拉式
                if (connectAreaInfo.PushPullMode == 1) {
                    for (var i = 0; i < rcvRecords.length; i++) {
                        rcvRecords[i].RowStatus = PublicEnum.RowStatus.Modify;
                        rcvRecords[i].Location = '-1';
                    }
                } else if (connectAreaInfo.PushPullMode == 0) {
                    //0:物流小车，1: 人工
                    if (connectAreaInfo.DeliveryMode == 1) {
                        for (var i = 0; i < rcvRecords.length; i++) {
                            rcvRecords[i].RowStatus = PublicEnum.RowStatus.Modify;
                            rcvRecords[i].Location = '-1';
                        }
                    } else if (connectAreaInfo.DeliveryMode == 0) {
                        //则将备货数据发送给物流小车（需现场确认逻辑）
                        //
                        for (var i = 0; i < rcvRecords.length; i++) {
                            rcvRecords[i].RowStatus = PublicEnum.RowStatus.Delete;
                        }
                    } else {
                        res.json({
                            Data: null,
                            Error: "无此种搬运工方式"
                        });
                    }

                } else {
                    res.json({
                        Data: null,
                        Error: "无此种推拉模式"
                    });
                }
                _.forEach(inRcvRecords, function (r) {
                    r.RowStatus = PublicEnum.RowStatus.Delete;
                });

                //提交品质记录与条码主档
                Transaction.BatchSaveByTran(
                    [
                        {EntityName: 'KanbanDemand', Records: kanbanArr},
                        {EntityName: 'RcvRecord', Records: rcvRecords},
                        {EntityName: 'RcvRecord', Records: inRcvRecords}
                    ],
                    function (err, result) {
                        if (err) {
                            res.json({
                                Data: null,
                                Error: err
                            });
                        }
                        else {
                            res.json({
                                Data: result,
                                Error: null
                            });
                        }
                    }
                );

            }, function (err) {
                res.json({
                    Data: null,
                    Error: err
                });
            });
        } else {
            res.json({
                Data: null,
                Error: "交接区为空或者对应的条码主档未找到"
            });
        }
    });
};

//交接区收货UpdateArrivedQty
exports.UpdateArrivedQty = function (req, res) {
    var parameter = req.body.Parameter,
        userId = parameter.userId,
        validBarcodeList = parameter.validBarcodeList;
    Q.all([
        getConnectArea(userId, false),
        queryByBarcodeAndGroupByMo('MO', validBarcodeList),
        getRcvRecordsByBarcode(validBarcodeList)
    ]).spread(function () {
        var connectAreaInfo = arguments[0],
            barcodeInfoArray = arguments[1],
            rcvRecords = arguments[2],
            MoArr = [],
            kanbanArr = [],
            rcvRecordsArr = [];

        if (connectAreaInfo && barcodeInfoArray.length > 0) {
            _.forEach(barcodeInfoArray, function (r) {
                MoArr.push(r._id);
            });
            getKanbanDemand({
                MO: {$in: MoArr},
                ConnectArea: connectAreaInfo._id
            }).then(function (data) {
                for (var i = 0; i < barcodeInfoArray.length; i++) {
                    _.forEach(data, function (r) {
                        if (barcodeInfoArray[i]._id.toString() == r.MO.toString() &&
                            connectAreaInfo._id.toString() == r.ConnectArea.toString()) {
                            r.TotalReceiveQty += barcodeInfoArray[i].value;
                            r.RowStatus = PublicEnum.RowStatus.Modify;
                        }
                    });
                }
                kanbanArr = data;
                //0:推式，1: 拉式
                if (connectAreaInfo.PushPullMode == 1) {
                    if (connectAreaInfo.DeliveryMode == 1) {
                        for (var i = 0; i < rcvRecords.length; i++) {
                            rcvRecords[i].RowStatus = PublicEnum.RowStatus.Delete;
                        }
                        rcvRecordsArr = rcvRecords;
                    } else if (connectAreaInfo.DeliveryMode == 0) {
                        for (var i = 0; i < rcvRecords.length; i++) {
                            if (rcvRecords[i].Location != null) {
                                rcvRecords[i].RowStatus = PublicEnum.RowStatus.Delete;
                                rcvRecordsArr.push(rcvRecords[i]);
                            }
                        }
                    } else {
                        res.json({
                            Data: null,
                            Error: "无此种搬运模式"
                        });
                    }
                } else if (connectAreaInfo.PushPullMode == 0 && connectAreaInfo.DeliveryMode == 1) {
                    //0:物流小车，1: 人工
                    for (var i = 0; i < rcvRecords.length; i++) {
                        rcvRecords[i].RowStatus = PublicEnum.RowStatus.Delete;
                    }
                    rcvRecordsArr = rcvRecords;
                } else {
                    res.json({
                        Data: null,
                        Error: "无此种推拉模式"
                    });
                }

                //提交品质记录与条码主档
                Transaction.BatchSaveByTran(
                    [
                        {EntityName: 'KanbanDemand', Records: kanbanArr},
                        {EntityName: 'RcvRecord', Records: rcvRecordsArr}
                    ],
                    function (err, result) {
                        if (err) {
                            res.json({
                                Data: null,
                                Error: err
                            });
                        }
                        else {
                            res.json({
                                Data: result,
                                Error: null
                            });
                        }
                    }
                );

            }, function (err) {
                res.json({
                    Data: null,
                    Error: err
                });
            });
        } else {
            res.json({
                Data: null,
                Error: "交接区为空或者对应的条码主档未找到"
            });
        }
    });
};

//交接检查是获取球拍的检查状态、重复扫描的合规性
exports.getBarcodeMasterInfo = function (req, res) {
    var parameter = req.body.Parameter,
        Barcode = parameter.Barcode;
    var entityRcvRecord = entityCollection.getEntity("RcvRecord"),
        entityBarcodeMaster = entityCollection.getEntity("BarcodeMaster");
    //现根据芯片ID检查入库记录，做重复扫描的合规性检查
    entityRcvRecord.findOne({Barcode: Barcode}, null, function (err, record) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
        }
        if (!record) {
            res.json({
                Data: "此球拍没有做入库或这是重复扫描",
                Error: null
            });
        } else {
            //接收芯片对应的条码主档
            entityBarcodeMaster.findOne({Barcode: Barcode}, null, function (err, record) {
                if (err) {
                    res.json({
                        Data: null,
                        Error: err
                    });
                }
                res.json({
                    Data: record,
                    Error: null
                });
            });
        }
    });
};

//通过用户ID获取交接区信息,flag == true(上游)，flag == false(下游)
function getConnectArea(userId, flag) {
    var deferred = Q.defer();
    var userModel = mongoose.model('User');
    //通过用户ID获取部门
    userModel.findOne({_id: userId}, {Department: 1}).exec(function (err, record) {
        if (err) {
            deferred.reject(err);
        }

        if (!record) {
            deferred.reject("用户对应部门为空");
        }
        var queryCondition = {};
        if (flag) {
            queryCondition = {UpDepartment: record.Department};
        } else {
            queryCondition = {DownDepartment: record.Department};
        }
        //通过用户部门获取交界区
        var entity = entityCollection.getEntity("ConnectArea");
        entity.findOne(queryCondition, null, function (err, result) {
            if (err) {
                deferred.reject(err);
            } else {
                deferred.resolve(result);
            }
        });
    });
    return deferred.promise;
}

//根据芯片ID(Barcode)，分组key,获取条码主档[key,value]
function queryByBarcodeAndGroupByMo(key, barcodeList) {
    var deferred = Q.defer();
    var entityBarcodeMaster = entityCollection.getEntity("BarcodeMaster");
    entityBarcodeMaster.aggregateCount(key, {Barcode: {$in: barcodeList}}, function (err, data) {
        if (err) {
            deferred.reject(err);
        }
        deferred.resolve(data);
    });
    return deferred.promise;
}

//根据交界区ID取得看板
function getKanbanDemand(condition) {
    var deferred = Q.defer();
    var entity = entityCollection.getEntity("KanbanDemand");
    entity.find(condition, null, null, function (err, results) {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(results);
        }
    });
    return deferred.promise;
}

//根据交接区ID获取入库记录
function getRvRecordsByConnectArea(connectAreaId) {
    var deferred = Q.defer();
    var entity = entityCollection.getEntity("RcvRecord");

    var barcodeMap = function () {
        emit(this.BusinessDocID, {barcode: this.BarcodeMaster, RcvQty: this.RcvQty});
    };

    var reduce = function (key, values) {
        return {barcode: this.BarcodeMaster, RcvQty: Array.sum(values.RcvQty)}
    };

    var query = {
        //connectAreaId: connectAreaId,
        //Location: null
    };

    var option = {
        map: barcodeMap,
        reduce: reduce,
        query: query
    };

    entity.mapReduce(option, function (err, results) {
        var barcodeModel = mongoose.model('BarcodeMaster');
        barcodeModel.populate(results, {path: 'value.barcode'}, function (err, resultsBarcodes) {
            deferred.resolve(resultsBarcodes);
        });
    });

    return deferred.promise;
}

//根据芯片ID(Barcode)获取入库记录
function getRcvRecordsByBarcode(barcodeList) {
    var deferred = Q.defer();
    var entity = entityCollection.getEntity("RcvRecord");
    entity.find({Barcode: {$in: [barcodeList]}}, null, null, function (err, records) {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(records);
        }
    });
    return deferred.promise;
}
